import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';

class RxDartConceptionPage extends StatefulWidget {
  RxDartConceptionPage({Key key}) : super(key: key);

  @override
  _RxDartConceptionPageState createState() => _RxDartConceptionPageState();
}

class _RxDartConceptionPageState extends State<RxDartConceptionPage> {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        ListTile(
          title: Text('Rx(Reactive Extensions)'),
        ),
        Divider(height: 2.0, color: Colors.black, thickness: 2.0),

        // ObservableCell
        ObservableCell(),
        Divider(height: 2.0, color: Colors.black, thickness: 2.0),

        // PublishSubjectCell
        PublishSubjectCell(),
        Divider(height: 2.0, color: Colors.black, thickness: 2.0),

        // BehaviorSubjectCell
        BehaviorSubjectCell(),
        Divider(height: 2.0, color: Colors.black, thickness: 2.0),

        // ReplaySubjectCell
        ReplaySubjectCell(),
        Divider(height: 2.0, color: Colors.black, thickness: 2.0),
      ],
    );
  }
}

/// ObservableCell
class ObservableCell extends StatelessWidget {
  const ObservableCell({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text('Observable'),
      subtitle: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          SingleChildScrollView(
            scrollDirection: Axis.horizontal,
            child: Text('''
List<String> fruits = ['apple', 'banana', 'orange', 'strawberry'];
Observable<String> observable = Observable(Stream.fromIterable(fruits));
_bservable.listen((data) {
  print(data);
});
                '''),
          ),
          SingleChildScrollView(
            scrollDirection: Axis.horizontal,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                RaisedButton(
                  child: Text('''Observable(Stream.fromIterable(fruits))'''),
                  onPressed: () {
                    List<String> fruits = ['apple', 'banana', 'orange', 'strawberry'];
                    Observable<String> observable = Observable(Stream.fromIterable(fruits));
                    observable.listen((data) {
                      print(data);
                    });
                  },
                ),
                RaisedButton(
                  child: Text('''Observable(Stream.fromFuture(Future.value('coder')))'''),
                  onPressed: () {
                    Observable<String> observable = Observable(Stream.fromFuture(Future.value('coder')));
                    observable.listen((data) {
                      print(data);
                    });
                  },
                ),
                RaisedButton(
                  child: Text('''Observable.fromIterable(fruits)'''),
                  onPressed: () {
                    List<String> fruits = ['apple', 'banana', 'orange', 'strawberry'];
                    Observable<String> observable = Observable.fromIterable(fruits);
                    observable.listen((data) {
                      print(data);
                    });
                  },
                ),
                RaisedButton(
                  child: Text('''Observable.fromFuture(Future.value('coder'))'''),
                  onPressed: () {
                    Observable<String> observable = Observable.fromFuture(Future.value('coder'));
                    observable.listen((data) {
                      print(data);
                    });
                  },
                ),
                RaisedButton(
                  child: Text('''Observable.just('coder')'''),
                  onPressed: () {
                    Observable<String> observable = Observable.just('coder');
                    observable.listen((data) {
                      print(data);
                    });
                  },
                ),
                RaisedButton(
                  child: Text('''Observable.periodic(Duration(seconds: 2), (x) => x.toString())'''),
                  onPressed: () {
                    // TODO: 还未释放
                    Observable<String> observable = Observable.periodic(Duration(seconds: 2), (x) => x.toString());
                    observable.listen((data) {
                      print(data);
                    });
                  },
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

/// PublishSubjectCell
class PublishSubjectCell extends StatelessWidget {
  const PublishSubjectCell({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text('PublishSubject'),
      subtitle: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          SingleChildScrollView(
            scrollDirection: Axis.horizontal,
            child: Text('''
- listen 在 add 之后无法监听到;
                  '''),
          ),
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  ListTile(
                    title: Text('situation_0:'),
                  ),
                  SingleChildScrollView(
                    scrollDirection: Axis.horizontal,
                    child: Text('''
PublishSubject<String> publishSubject = PublishSubject<String>();

publishSubject.listen((data) => print('Listen0: ' + data));
publishSubject.listen((data) => print('Listen1: ' + data));
publishSubject.add('PublishSubject A');
publishSubject.add('PublishSubject B');

/**
   * flutter: Listen0: PublishSubject A
   * flutter: Listen1: PublishSubject A
   * flutter: Listen0: PublishSubject B
   * flutter: Listen1: PublishSubject B
   */

publishSubject.close();
                    '''),
                  ),
                  RaisedButton(
                    child: Text('init'),
                    onPressed: () {
                      PublishSubject<String> publishSubject = PublishSubject<String>();

                      publishSubject.listen((data) => print('Listen0: ' + data));
                      publishSubject.listen((data) => print('Listen1: ' + data));
                      publishSubject.add('PublishSubject A');
                      publishSubject.add('PublishSubject B');

                      /**
                         * flutter: Listen0: PublishSubject A
                         * flutter: Listen1: PublishSubject A
                         * flutter: Listen0: PublishSubject B
                         * flutter: Listen1: PublishSubject B
                         */

                      publishSubject.close();
                    },
                  ),
                ],
              ),
            ],
          ),
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              ListTile(
                title: Text('situation_1:'),
              ),
              SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                child: Text('''
PublishSubject<String> publishSubject = PublishSubject<String>();

publishSubject.listen((data) => print('Listen0: ' + data));
publishSubject.add('PublishSubject A');
publishSubject.listen((data) => print('Listen1: ' + data));
publishSubject.add('PublishSubject B');

/**
 * flutter: Listen0: PublishSubject A
 * flutter: Listen1: PublishSubject B
 * flutter: Listen0: PublishSubject B
 */

publishSubject.close();
                '''),
              ),
              RaisedButton(
                child: Text('init'),
                onPressed: () {
                  PublishSubject<String> publishSubject = PublishSubject<String>();

                  publishSubject.listen((data) => print('Listen0: ' + data));
                  publishSubject.add('PublishSubject A');
                  publishSubject.listen((data) => print('Listen1: ' + data));
                  publishSubject.add('PublishSubject B');

                  /**
                   * flutter: Listen0: PublishSubject A
                   * flutter: Listen1: PublishSubject B
                   * flutter: Listen0: PublishSubject B
                   */

                  publishSubject.close();
                },
              ),
            ],
          )
        ],
      ),
    );
  }
}

/// BehaviorSubjectCell
class BehaviorSubjectCell extends StatelessWidget {
  const BehaviorSubjectCell({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text('BehaviorSubject'),
      subtitle: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          SingleChildScrollView(
            scrollDirection: Axis.horizontal,
            child: Text('''
- 可以把最后一次添加的数据作为第一个项目交给新来的监听
                  '''),
          ),
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  ListTile(
                    title: Text('situation_0:'),
                  ),
                  SingleChildScrollView(
                    scrollDirection: Axis.horizontal,
                    child: Text('''
BehaviorSubject<String> behaviorSubject = BehaviorSubject<String>();

behaviorSubject.listen((data) => print('Listen0: ' + data));
behaviorSubject.listen((data) => print('Listen1: ' + data));
behaviorSubject.add('PublishSubject A');
behaviorSubject.add('PublishSubject B');

/**
 * flutter: Listen0: PublishSubject A
 * flutter: Listen1: PublishSubject A
 * flutter: Listen0: PublishSubject B
 * flutter: Listen1: PublishSubject B
 */

behaviorSubject.close();
                          '''),
                  ),
                  RaisedButton(
                    child: Text('init'),
                    onPressed: () {
                      BehaviorSubject<String> behaviorSubject = BehaviorSubject<String>();

                      behaviorSubject.listen((data) => print('Listen0: ' + data));
                      behaviorSubject.listen((data) => print('Listen1: ' + data));
                      behaviorSubject.add('PublishSubject A');
                      behaviorSubject.add('PublishSubject B');

                      /**
                         * flutter: Listen0: PublishSubject A
                         * flutter: Listen1: PublishSubject A
                         * flutter: Listen0: PublishSubject B
                         * flutter: Listen1: PublishSubject B
                         */

                      behaviorSubject.close();
                    },
                  ),
                ],
              ),
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  ListTile(
                    title: Text('situation_1'),
                  ),
                  SingleChildScrollView(
                    scrollDirection: Axis.horizontal,
                    child: Text('''
BehaviorSubject<String> behaviorSubject = BehaviorSubject<String>();

behaviorSubject.listen((data) => print('Listen0: ' + data));
behaviorSubject.add('PublishSubject A');
behaviorSubject.add('PublishSubject X');
behaviorSubject.add('PublishSubject Y');
behaviorSubject.add('PublishSubject Z');
behaviorSubject.listen((data) => print('Listen1: ' + data));
behaviorSubject.add('PublishSubject B');

/**
 * flutter: Listen0: PublishSubject A
 * flutter: Listen1: PublishSubject Z // 最后添加的数据, 作为第一个项目交给新来的监听 Listen1
 * flutter: Listen1: PublishSubject B
 * flutter: Listen0: PublishSubject X
 * flutter: Listen0: PublishSubject Y
 * flutter: Listen0: PublishSubject Z
 * flutter: Listen0: PublishSubject B
 */

behaviorSubject.close();
                          '''),
                  ),
                  RaisedButton(
                    child: Text('init'),
                    onPressed: () {
                      BehaviorSubject<String> behaviorSubject = BehaviorSubject<String>();

                      behaviorSubject.listen((data) => print('Listen0: ' + data));
                      behaviorSubject.add('PublishSubject A');
                      behaviorSubject.add('PublishSubject X');
                      behaviorSubject.add('PublishSubject Y');
                      behaviorSubject.add('PublishSubject Z');
                      behaviorSubject.listen((data) => print('Listen1: ' + data));
                      behaviorSubject.add('PublishSubject B');

                      /**
                         * flutter: Listen0: PublishSubject A
                         * flutter: Listen1: PublishSubject Z // 最后添加的数据, 作为第一个项目交给新来的监听 Listen1
                         * flutter: Listen1: PublishSubject B
                         * flutter: Listen0: PublishSubject X
                         * flutter: Listen0: PublishSubject Y
                         * flutter: Listen0: PublishSubject Z
                         * flutter: Listen0: PublishSubject B
                         */

                      behaviorSubject.close();
                    },
                  )
                ],
              ),
            ],
          ),
        ],
      ),
    );
  }
}

/// ReplaySubjectCell
class ReplaySubjectCell extends StatelessWidget {
  const ReplaySubjectCell({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text('ReplaySubjectCell'),
      subtitle: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          SingleChildScrollView(
            scrollDirection: Axis.horizontal,
            child: Text('''
- 可以将所有添加到 Controller 或 Subject 的所有数据交给监听器;
            '''),
          ),
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              ListTile(
                title: Text('situation_0:'),
              ),
              SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                child: Text('''
ReplaySubject<String> behaviorSubject = ReplaySubject<String>();

behaviorSubject.add('PublishSubject A');
behaviorSubject.add('PublishSubject B');
behaviorSubject.add('PublishSubject C');
behaviorSubject.listen((data) => print('Listen0: ' + data));
behaviorSubject.listen((data) => print('Listen1: ' + data));

/**
 * flutter: Listen0: PublishSubject A
 * flutter: Listen1: PublishSubject A
 * flutter: Listen0: PublishSubject B
 * flutter: Listen1: PublishSubject B
 * flutter: Listen0: PublishSubject C
 * flutter: Listen1: PublishSubject C
 */

behaviorSubject.close();
                '''),
              ),
              RaisedButton(
                child: Text('init'),
                onPressed: () {
                  ReplaySubject<String> behaviorSubject = ReplaySubject<String>();

                  behaviorSubject.add('PublishSubject A');
                  behaviorSubject.add('PublishSubject B');
                  behaviorSubject.add('PublishSubject C');
                  behaviorSubject.listen((data) => print('Listen0: ' + data));
                  behaviorSubject.listen((data) => print('Listen1: ' + data));

                  /**
                   * flutter: Listen0: PublishSubject A
                   * flutter: Listen1: PublishSubject A
                   * flutter: Listen0: PublishSubject B
                   * flutter: Listen1: PublishSubject B
                   * flutter: Listen0: PublishSubject C
                   * flutter: Listen1: PublishSubject C
                   */

                  behaviorSubject.close();
                },
              ),
            ],
          ),
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              ListTile(
                title: Text('situation_1:'),
              ),
              SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                child: Text('''
ReplaySubject<String> behaviorSubject = ReplaySubject<String>();

behaviorSubject.listen((data) => print('Listen0: ' + data));
behaviorSubject.add('PublishSubject A');
behaviorSubject.add('PublishSubject X');
behaviorSubject.add('PublishSubject Y');
behaviorSubject.add('PublishSubject Z');
behaviorSubject.listen((data) => print('Listen1: ' + data));
behaviorSubject.add('PublishSubject B');

/**
 * flutter: Listen0: PublishSubject A
 * flutter: Listen1: PublishSubject A
 * flutter: Listen0: PublishSubject X
 * flutter: Listen1: PublishSubject X
 * flutter: Listen0: PublishSubject Y
 * flutter: Listen1: PublishSubject Y
 * flutter: Listen0: PublishSubject Z
 * flutter: Listen1: PublishSubject Z
 * flutter: Listen0: PublishSubject B
 * flutter: Listen1: PublishSubject B
 */

behaviorSubject.close();
                '''),
              ),
              RaisedButton(
                child: Text('init'),
                onPressed: () {
                  ReplaySubject<String> behaviorSubject = ReplaySubject<String>();

                  behaviorSubject.listen((data) => print('Listen0: ' + data));
                  behaviorSubject.add('PublishSubject A');
                  behaviorSubject.add('PublishSubject X');
                  behaviorSubject.add('PublishSubject Y');
                  behaviorSubject.add('PublishSubject Z');
                  behaviorSubject.listen((data) => print('Listen1: ' + data));
                  behaviorSubject.add('PublishSubject B');

                  /**
                   * flutter: Listen0: PublishSubject A
                   * flutter: Listen1: PublishSubject A
                   * flutter: Listen0: PublishSubject X
                   * flutter: Listen1: PublishSubject X
                   * flutter: Listen0: PublishSubject Y
                   * flutter: Listen1: PublishSubject Y
                   * flutter: Listen0: PublishSubject Z
                   * flutter: Listen1: PublishSubject Z
                   * flutter: Listen0: PublishSubject B
                   * flutter: Listen1: PublishSubject B
                   */

                  behaviorSubject.close();
                },
              ),
            ],
          ),
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              ListTile(
                title: Text('situation_2 <maxSize>:'),
              ),
              SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                child: Text('''
ReplaySubject<String> behaviorSubject = ReplaySubject<String>(maxSize: 2);

behaviorSubject.add('PublishSubject A');
behaviorSubject.add('PublishSubject B');
behaviorSubject.add('PublishSubject C');
behaviorSubject.add('PublishSubject D');
behaviorSubject.listen((data) => print('Listen0: ' + data));

/**
 * flutter: Listen0: PublishSubject C
 * flutter: Listen0: PublishSubject D
 */

behaviorSubject.close();
                '''),
              ),
              RaisedButton(
                child: Text('init'),
                onPressed: () {
                  ReplaySubject<String> behaviorSubject = ReplaySubject<String>(maxSize: 2);

                  behaviorSubject.add('PublishSubject A');
                  behaviorSubject.add('PublishSubject B');
                  behaviorSubject.add('PublishSubject C');
                  behaviorSubject.add('PublishSubject D');
                  behaviorSubject.listen((data) => print('Listen0: ' + data));

                  /**
                   * flutter: Listen0: PublishSubject C
                   * flutter: Listen0: PublishSubject D
                   */

                  behaviorSubject.close();
                },
              ),
            ],
          ),
        ],
      ),
    );
  }
}
